from __future__ import print_function

import numpy as np
from scipy.stats import norm
import csv


def encode_label(y, test=False):
    """
    Run encoding to encode the label into the CDF target.
    """
    systole = np.zeros((y.shape[0], 600))
    diastole = np.zeros((y.shape[0], 600))
    if test:
        systole_cdf = np.array(systole)
        diastole_cdf = np.array(diastole)
    for i in range(len(y)):
        temp_0 = np.zeros((600, ))
        temp_1 = np.zeros((600, ))
        temp_0[int(y[i, 0])+1] = 1
        temp_1[int(y[i, 1])+1] = 1
        systole[i, :] = temp_0
        diastole[i, :] = temp_1
        if test:
            systole_cdf[i, :] = np.cumsum(temp_0)
            diastole_cdf[i, :] = np.cumsum(temp_1)
    if test:
        return systole, diastole, systole_cdf, diastole_cdf

    return systole, diastole


def output_to_proba(y):
    """
    Convert y (output) to probabilities.
    """
    y_0, y_1 = encode_label(y, test=False)
    y_proba = np.zeros((y.shape[0], y.shape[1], 600))
    y_proba[:, 0] = y_0
    y_proba[:, 1] = y_1

    return y_proba


def output_to_cdf(y):
    """
    Convert y (output) to CDF.
    """
    y_0, y_1, y_0_cdf, y_1_cdf = encode_label(y, test=True)
    y_cdf = np.zeros((y.shape[0], y.shape[1], 600))
    y_cdf[:, 0] = y_0_cdf
    y_cdf[:, 1] = y_1_cdf

    return y_cdf


def real_to_cdf(y, sigma=1e-10):
    cdf = np.zeros((y.shape[0], 600))
    for i in range(len(y)):
        cdf[i] = norm.cdf(np.linspace(0, 599, 600), y[i], sigma)
    return cdf


def crps(label, pred):
    """
    Custom evaluation metric on CRPS.
    """
    for i in range(pred.shape[0]):
        for j in range(pred.shape[1] - 1):
            if pred[i, j] > pred[i, j + 1]:
                pred[i, j + 1] = pred[i, j]
    for i in range(label.shape[0]):
        for j in range(label.shape[1] - 1):
            if label[i, j] > label[i, j + 1]:
                label[i, j + 1] = label[i, j]
    return np.sum(np.square(label - pred)) / label.size

